package com.acoreful.sample.commons.utils;

import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;

/**
 * @author Acore
 *
 */
public class PropertiesUtils {
	private static Logger logger = LoggerFactory
			.getLogger(PropertiesUtils.class);
	private static final String PLACEHOLDER_START = "${";
	private static Properties pro;

	/**
	 * @param path
	 * @return
	 */
	public static Properties loadPropertiesFileFromClassPath(String path) {
		Properties config = new Properties();
		try {
			config.load(new ClassPathResource(path).getInputStream());
		} catch (IOException e) {
			logger.error("load properties file error: {}", e.getMessage());
		}
		return config;
	}

	/**
	 * 打印
	 * @param p
	 */
	@SuppressWarnings("rawtypes")
	public static void printProperties(Properties p) {
		Iterator it = p.entrySet().iterator();
		while (it.hasNext()) {
			Entry ent = (Entry) it.next();
			System.out.println(ent.getKey() + " : " + ent.getValue());
		}
	}

	/**
	 * 解析占位符
	 * 
	 * @param properties
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static void resolvePlaceHolders(Properties properties) {
		Iterator itr = properties.entrySet().iterator();
		while (itr.hasNext()) {
			final Map.Entry entry = (Map.Entry) itr.next();
			final Object value = entry.getValue();
			if (value != null && String.class.isInstance(value)) {
				final String resolved = resolvePlaceHolder((String) value);
				if (!value.equals(resolved)) {
					if (resolved == null) {
						itr.remove();
					} else {
						entry.setValue(resolved);
					}
				}
			}
		}
	}

	/**
	 * 解析占位符具体操作
	 * 
	 * @param property
	 * @return
	 */
	public static String resolvePlaceHolder(String property) {
		if (property.indexOf(PLACEHOLDER_START) < 0) {
			return property;
		}
		StringBuffer buff = new StringBuffer();
		char[] chars = property.toCharArray();
		for (int pos = 0; pos < chars.length; pos++) {
			if (chars[pos] == '$') {
				// peek ahead
				if (chars[pos + 1] == '{') {
					// we have a placeholder, spin forward till we find the end
					String propertyKey = "";
					int x = pos + 2;
					for (; x < chars.length && chars[x] != '}'; x++) {
						propertyKey += chars[x];
						// if we reach the end of the string w/o finding the
						// matching end, that is an exception
						if (x == chars.length - 1) {
							throw new IllegalArgumentException(
									"unmatched placeholder start [" + property
											+ "]");
						}
					}
					String propertyValue = extractFromSystem(propertyKey);
					propertyValue=isEmpty(propertyValue)?extractFromProp(propertyKey):propertyValue;
					buff.append(propertyValue == null ? "" : propertyValue);
					pos = x + 1;
					// make sure spinning forward did not put us past the end of
					// the buffer...
					if (pos >= chars.length) {
						break;
					}
				}
			}
			buff.append(chars[pos]);
		}
		String rtn = buff.toString();
		return isEmpty(rtn) ? null : rtn;
	}

	/**
	 * 构造properties文件
	 * 
	 * @param path
	 * @throws IOException
	 */
	public static Properties buildProperty(String path) throws IOException {
		InputStream is = getResourceAsStream(path);
		pro = new Properties();
		pro.load(is);
		return pro;
	}

	/**
	 * 构造properties文件的流
	 * 
	 * @param resource
	 * @return
	 */
	public static InputStream getResourceAsStream(String resource) {
		String stripped = resource.startsWith("/") ? resource.substring(1)
				: resource;

		InputStream stream = null;
		ClassLoader classLoader = Thread.currentThread()
				.getContextClassLoader();
		if (classLoader != null) {
			stream = classLoader.getResourceAsStream(stripped);
		}
		if (stream == null) {
			stream = PropertiesUtils.class.getResourceAsStream(resource);
		}
		if (stream == null) {
			stream = PropertiesUtils.class.getClassLoader()
					.getResourceAsStream(stripped);
		}
		if (stream == null) {
			throw new RuntimeException(resource + " not found");
		}
		return stream;
	}

	/**
	 * 获得系统属性 当然 你可以选择从别的地方获取值
	 * 
	 * @param systemPropertyName
	 * @return
	 */
	private static String extractFromSystem(String systemPropertyName) {
		try {
			return System.getProperty(systemPropertyName);
		} catch (Throwable t) {
			return null;
		}
	}
	/**
	 * @param key
	 * @return
	 */
	private static String extractFromProp(String key) {
		try {
			if(pro==null){
				return null;
			}
			return pro.getProperty(key);
		} catch (Throwable t) {
			return null;
		}
	}

	/**
	 * 判断字符串的空(null或者.length=0)
	 * 
	 * @param string
	 * @return
	 */
	public static boolean isEmpty(String string) {
		return string == null || string.length() == 0;
	}

	public static void main(String[] args) {

		try {
			pro = buildProperty("config.properties");
			resolvePlaceHolders(pro);
			printProperties(pro);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
